package io.itit.ecp.admin.provide.action.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import icu.mhb.mybatisplus.plugln.core.JoinLambdaWrapper;
import icu.mhb.mybatisplus.plugln.extend.Joins;
import io.itit.ecp.admin.common.constants.ParamConstants;
import io.itit.ecp.admin.common.enums.IDataRangeEnums;
import io.itit.ecp.admin.provide.action.req.SceneProjectQueryReq;
import io.itit.ecp.admin.provide.action.req.SceneProjectReq;
import io.itit.ecp.admin.provide.action.resp.SceneProjectResp;
import io.itit.ecp.admin.provide.filter.ISceneProjectFilter;
import io.itit.ecp.admin.provide.helper.DataRangeHelper;
import io.itit.ecp.admin.provide.renderer.SceneProjectRenderer;
import io.itit.ecp.admin.server.entity.SceneProjectEntity;
import io.itit.ecp.admin.server.service.ISceneProjectService;
import io.itit.grass.common.exception.GrassException;
import io.itit.grass.common.provide.action.req.BaseBatchIdReq;
import io.itit.grass.common.provide.action.req.BaseIdReq;
import io.itit.grass.common.provide.action.resp.ResultResp;
import io.itit.grass.common.provide.action.validation.*;
import io.itit.grass.common.server.utils.ConvertUtils;
import io.itit.grass.core.server.entity.UserEntity;
import io.itit.grass.core.server.service.IUserService;
import io.itit.grass.estelle.starter.core.ExcelXSSFUtil;
import io.itit.grass.estelle.starter.parse.ExcelParseManage;
import io.itit.grass.estelle.starter.util.JsonUtil;
import io.itit.grass.web.wall.utils.PageUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 *
 * @Author：Roy
 * @Description：项目管理控制类
 * @Date：Create by 2023-11-23 11:46:13
 */
@Api(tags = "项目管理")
@RestController
@RequestMapping("/ecp-admin/sceneProject/")
public class SceneProjectController {

    @Resource
    private ISceneProjectService sceneProjectService;

    @Resource
    private IUserService userService;

    @ApiOperation("分页查询")
    @PostMapping("queryPage")
    @RequiresPermissions("ecp-admin:sceneProject:search")
    public ResultResp<IPage<SceneProjectResp>> queryPage(@RequestBody @Validated(IQueryPage.class) SceneProjectQueryReq req) {
        Page<SceneProjectResp> page = buildQW(req).joinPage(PageUtils.getPage(req, SceneProjectResp.class), SceneProjectResp.class);
        return ResultResp.success(page);
    }

    @ApiOperation("列表查询")
    @PostMapping("queryList")
    @RequiresPermissions(value = {"ecp-admin:sceneProject:search", "ecp-admin:carbonEmissionReport:search"}, logical = Logical.OR)
    public ResultResp<List<SceneProjectResp>> queryList(@RequestBody SceneProjectQueryReq req) {
        List<SceneProjectResp> list = buildQW(req).joinList(SceneProjectResp.class);
        return ResultResp.success(list);
    }

    @ApiOperation("详情")
    @PostMapping("detail")
    public ResultResp<SceneProjectResp> detail(@RequestBody @Validated(IRequired.class) BaseIdReq req) {
        SceneProjectResp resp = ConvertUtils.copy(sceneProjectService.getById(req.getId()), SceneProjectResp.class);
        if (Objects.nonNull(resp)) {
            UserEntity user = userService.getById(resp.getUserId());
            if (Objects.nonNull(user)) {
                resp.setUserName(user.getUserName());
            }
        }
        return ResultResp.success(resp);
    }


    /**
     * 组装查询条件
     */
    private static JoinLambdaWrapper<SceneProjectEntity> buildQW(SceneProjectQueryReq req) {
        // 如果数据范围权限小于项目级别就不能查询项目数据
        if (IDataRangeEnums.RangeLevel.getLevel(DataRangeHelper.i().getDataRangeLevel()) > 2) {
            return Joins.of(SceneProjectEntity.class).last(ParamConstants.LIMIT_ZERO);
        }
        return Joins.of(SceneProjectEntity.class)
                .selectAll()
                .leftJoin(UserEntity.class, UserEntity::getId, SceneProjectEntity::getUserId)
                .like(StringUtils.isNotEmpty(req.getUserName()), UserEntity::getUserName, req.getUserName())
                .select(UserEntity::getUserName, UserEntity::getMobilePhone)
                .end()
                .eq(StringUtils.isNotEmpty(req.getProjectName()), SceneProjectEntity::getProjectName, req.getProjectName())
                .eq(StringUtils.isNotEmpty(req.getAddress()), SceneProjectEntity::getAddress, req.getAddress())
                .eq(StringUtils.isNotEmpty(req.getDeliverTime()), SceneProjectEntity::getDeliverTime, req.getDeliverTime())
                .eq(req.getLandArea() != null, SceneProjectEntity::getLandArea, req.getLandArea())
                .eq(req.getFloorArea() != null, SceneProjectEntity::getFloorArea, req.getFloorArea())
                .eq(StringUtils.isNotEmpty(req.getUserId()), SceneProjectEntity::getUserId, req.getUserId())
                .eq(req.getStatus() != null, SceneProjectEntity::getStatus, req.getStatus())
                .in(CollectionUtils.isNotEmpty(req.getStatusList()), SceneProjectEntity::getStatus, req.getStatusList())
                .eq(StringUtils.isNotEmpty(req.getDeptId()), SceneProjectEntity::getDeptId, req.getDeptId())
                .in(CollectionUtils.isNotEmpty(req.getIds()), SceneProjectEntity::getId, req.getIds())
                .last(StringUtils.isNotEmpty(req.getSortColumn()), PageUtils.lastOrderBy(req))
                .orderByDesc(SceneProjectEntity::getCreateTm);
    }

    @ApiOperation("新增")
    @PostMapping("add")
    @RequiresPermissions("ecp-admin:sceneProject:add")
    public ResultResp<Boolean> add(@RequestBody @Validated({IAdd.class}) SceneProjectReq req) {
        checkDataExists(req);
        return ResultResp.success(sceneProjectService.save(ConvertUtils.convertIgnoreId(req, SceneProjectEntity.class)));
    }

    @ApiOperation("编辑")
    @PostMapping("update")
    @RequiresPermissions("ecp-admin:sceneProject:update")
    public ResultResp<Boolean> update(@RequestBody @Validated({IUpdate.class}) SceneProjectReq req) {
        checkDataExists(req);
        return ResultResp.success(sceneProjectService.updateById(ConvertUtils.copy(req, SceneProjectEntity.class)));
    }

    private void checkDataExists(SceneProjectReq req) {
        Long count = sceneProjectService.lambdaQuery()
                .eq(SceneProjectEntity::getProjectName, req.getProjectName())
                .ne(StringUtils.isNotEmpty(req.getId()), SceneProjectEntity::getId, req.getId())
                .count();
        GrassException.throwEx(count > 0, "项目名称已存在！");
    }

    @ApiOperation("删除(根据Id删)")
    @PostMapping("deleteById")
    @RequiresPermissions("ecp-admin:sceneProject:deleteById")
    public ResultResp<Boolean> deleteById(@RequestBody @Validated({IRequired.class}) BaseIdReq req) {
        return ResultResp.success(sceneProjectService.removeProjects(Collections.singletonList(req.getId())));
    }

    @ApiOperation("批量删除")
    @PostMapping("batchDelete")
    @RequiresPermissions("ecp-admin:sceneProject:batchDelete")
    public ResultResp<Boolean> batchDelete(@RequestBody @Validated({IRequired.class}) BaseBatchIdReq req) {
        return ResultResp.success(sceneProjectService.removeProjects(req.getIds()));
    }

    @ApiOperation("导入")
    @PostMapping("upload")
    @RequiresPermissions("ecp-admin:sceneProject:upload")
    public ResultResp<Integer> upload(@RequestParam("file") MultipartFile file, Boolean ignoreError) {
        return ResultResp.success(ExcelParseManage.i().process(SceneProjectRenderer.ENTITY_NAME, file, ignoreError));
    }

    @ApiOperation("导出")
    @PostMapping("export")
    @RequiresPermissions("ecp-admin:sceneProject:export")
    public void export(@RequestBody @Validated(IExport.class) SceneProjectQueryReq req, HttpServletResponse response) {
        ExcelXSSFUtil.export("SceneProjectExport", JsonUtil.toJson(sceneProjectService.list(buildQW(req)), new ISceneProjectFilter.SceneProjectExportFilter()), response);
    }
}
